package org.robotlegs.xxl.base 
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	import org.osflash.signals.natives.sets.DisplayObjectSignalSet;
	import org.robotlegs.core.IInjector;
	import org.robotlegs.core.IViewMap;
	/**
	 * 基于Robotlegs的ViewMap，用Signal替换了原有的事件机制
	 * @author XXL
	 */
	public class ViewMap extends ViewMapBase implements IViewMap 
	{
		protected var mappedPackages:Array;
		protected var mappedTypes:Dictionary;
		protected var injectedViews:Dictionary;
		
		public function ViewMap(contextView:DisplayObjectContainer,injector:IInjector) 
		{
			super(contextView, injector);
			
			mappedPackages = [];
			mappedTypes = new Dictionary();
			injectedViews = new Dictionary(true);
		}
		
		private function injectInto(target:DisplayObject):void 
		{
			injector.injectInto(target);
			injectedViews[target] = true;
		}
		
		protected var signalSet:DisplayObjectSignalSet;
		override protected function addListeners():void 
		{
			if (contextView && enabled)
			{
				signalSet = new DisplayObjectSignalSet(contextView);
				signalSet.addedToStage.add(onViewAdded);
				signalSet.added.add(onViewAdded);
			}
		}
		
		override protected function removeListeners():void 
		{
			if (signalSet)
			{
				signalSet.removeAll();
			}
		}
		
		protected function onViewAdded(e:Event):void 
		{
			var target:DisplayObject = e.target as DisplayObject;
			if (injectedViews[target])
			{
				return;
			}
			for each(var type:Class in mappedTypes)
			{
				if (target is type)
				{
					injectInto(target);
					return;
				}
			}
			
			var len:int = mappedPackages.length;
			if (len > 0)
			{
				var className:String = getQualifiedClassName(target);
				for (var i:int = 0; i < len; i++) 
				{
					var packageName:String = mappedPackages[i];
					if (className.indexOf(packageName) == 0)
					{
						injectInto(target);
						return;
					}
				}
			}
		}
		
		/* INTERFACE org.robotlegs.core.IViewMap */
		
		public function mapPackage(packageName:String):void 
		{
			if (mappedPackages.indexOf(packageName) == -1)
			{
				mappedPackages.push(packageName);
				viewListenerCount++;
				if (viewListenerCount == 1)
				{
					addListeners();
				}
			}
		}
		
		public function unmapPackage(packageName:String):void 
		{
			var index:int = mappedPackages.indexOf(packageName);
			if (index > -1)
			{
				mappedPackages.splice(index, 1);
				viewListenerCount--;
				if (viewListenerCount == 0)
				{
					removeListeners();
				}
			}
		}
		
		public function hasPackage(packageName:String):Boolean 
		{
			return mappedPackages.indexOf(packageName) > -1;
		}
		
		public function mapType(type:Class):void 
		{
			if (mappedTypes[type])
			{
				return;
			}
			mappedTypes[type] = type;
			
			viewListenerCount++;
			if (viewListenerCount == 1)
			{
				addListeners();
			}
			if (contextView && (contextView is type))
			{
				injectInto(contextView);
			}
		}
		
		public function unmapType(type:Class):void 
		{
			var mapping:Class = mappedTypes[type];
			delete mappedTypes[type];
			if (mapping)
			{
				viewListenerCount--;
				if (viewListenerCount == 0)
				{
					removeListeners();
				}
			}
		}
		
		public function hasType(type:Class):Boolean 
		{
			return (mappedTypes[type] != null);
		}
		
	}

}